import collections
from hte.error.models import HTEError
from django.http import HttpResponse
import json
from django.core.serializers.json import DjangoJSONEncoder
from django.utils.functional import Promise
from bson.objectid import ObjectId
from django.utils.encoding import force_text
from datetime import datetime
from django.utils import timezone
from apps.storage.models.material import MaterialCategory
from apps.storage.models.dataset import DataSet
import pandas as pd
from apps.mlplatform.ml_handle.utils import read_dataset


class LazyEncoder(DjangoJSONEncoder):
    def default(self, obj):
        if isinstance(obj, (Promise, ObjectId)):
            return force_text(obj)
        if isinstance(obj, datetime):
            obj = timezone.localtime(obj)
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        return super(LazyEncoder, self).default(obj)


def general_response_data(data, errCode=0, errMsg='成功'):
    data_json = collections.OrderedDict()
    data_json['errCode'] = errCode
    data_json['errMsg'] = errMsg
    data_json['data'] = data
    return data_json


def json_response(data=None, msg: str = 'successfully', status_code: int = 200, **kwargs) -> HttpResponse:
    """
    将字典数据转为JSON返回（正常返回数据，错误代码为0即成功）
    :param data: 需要返回的数据
    :param msg: 提示消息
    :param status_code: http 状态码，默认 200
    :param kwargs: 附加信息，直接嵌入JSON第一级
    :return: None
    """
    result = {'errCode': HTEError.SUCCESS,
              'errMsg': msg,
              'data': data, }
    return HttpResponse(json.dumps(result, ensure_ascii=False, cls=LazyEncoder),
                        content_type='application/json; charset=utf-8',
                        status=status_code)


def get_all_children(parent: MaterialCategory):
    data = parent.to_dict()
    data['children'] = []
    children = MaterialCategory.objects.filter(parent_id=parent.id)
    if len(children) == 0:
        return data
    else:
        for child in children:
            data['children'].append(get_all_children(child))
        return data


def get_dataset_info(dataset: DataSet):
    file_abs_path = dataset.get_abs_file_path()
    data = read_dataset(file_abs_path)
    indexs = get_dataset_index(data)
    rows, cols = get_dataset_col_row(data)
    return indexs, rows, cols


def get_dataset_index(df: pd.DataFrame):
    indexs = list(df.columns)
    return indexs


def get_dataset_col_row(df: pd.DataFrame):
    rows = df.shape[0]
    cols = df.shape[1]
    return rows, cols
